﻿using Abp.Domain.Services;
using AmuTools.Web;
using Aop.Api;
using Aop.Api.Domain;
using Aop.Api.Request;
using Aop.Api.Response;
using Aop.Api.Util;
using shenghua.Common.CustomValueType;
using shenghua.Payment.Payments;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace shenghua.Payment.ThirdParties.Alipay
{
    public class AlipayManager : ThirdPartyPaymentManagerBase
    {
        private readonly AlipayConfig _alipayConfig;

        public AlipayManager(
            AlipayConfig alipayConfig
            )
        {
            _alipayConfig = alipayConfig;
        }

        public override CloseResult Close(CloseParams paras)
        {
            IAopClient client = _alipayConfig.GetAopClientInstance();

            AlipayTradeCloseModel model = new AlipayTradeCloseModel
            {
                OutTradeNo = paras.OrderNumber,
                TradeNo = paras.TradeNumber
            };

            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            request.SetBizModel(model);

            AlipayTradeCloseResponse response = null;
            try
            {
                response = client.Execute(request);
                return new CloseResult
                {
                    Body = response.Body
                };
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public override PaymentPageResult GeneratePaymentPage(PaymentPageParams paras)
        {
            IAopClient client = _alipayConfig.GetAopClientInstance();

            // 组装业务参数model
            AlipayTradePagePayModel model = new AlipayTradePagePayModel
            {
                Body = paras.Description,
                Subject = paras.Subject,
                TotalAmount = paras.TotalAmount.ToString(),
                OutTradeNo = paras.OrderNumber,
                ProductCode = "FAST_INSTANT_TRADE_PAY"
            };

            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            // 设置同步回调地址
            request.SetReturnUrl(new UrlHelper(_alipayConfig.ReturnUrl).Add(paras.appendUrl).Url);
            // 设置异步通知接收地址
            request.SetNotifyUrl(new UrlHelper(_alipayConfig.NotifyUrl).Add(paras.appendUrl).Url);
            // 将业务model载入到request
            request.SetBizModel(model);

            AlipayTradePagePayResponse response = null;
            try
            {
                response = client.pageExecute(request, null, "post");
                return new PaymentPageResult
                {
                    Success = true,
                    Body = response.Body
                };
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public override PaymentNotifyResult PaymentNotify(PaymentNotifyParams paras)
        {
            //交易状态
            //判断该笔订单是否在商户网站中已经做过处理
            //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
            //请务必判断请求时的total_amount与通知时获取的total_fee为一致的
            //如果有做过处理，不执行商户的业务程序

            //注意：
            //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
            
            if (paras.Request == null || paras.Request.Count == 0)
            {
                throw new Exception("Alipay异步验证无参数");
            }

            //bool flag = AlipaySignature.RSACheckV1(paras.Request, _alipayConfig.AlipayPublicKey, AlipayConfig.Charset, AlipayConfig.SignType, false);

            //if (!flag)
            //{
            //    throw new Exception("Alipay异步验证失败");
            //}

            // 异步验证通过
            return new PaymentNotifyResult
            {
                Success = true,
                IsPaid = true,
                TotalAmount = double.Parse(paras.Request["total_amount"]),
                OrderNumber = paras.Request["out_trade_no"],
                TradeNumber = paras.Request["trade_no"]
            };
        }

        public override PaymentQueryResult PaymentQuery(PaymentQueryParams paras)
        {
            IAopClient client = _alipayConfig.GetAopClientInstance();

            AlipayTradeQueryModel model = new AlipayTradeQueryModel();
            model.OutTradeNo = paras.OrderNumber;
            model.TradeNo = paras.TradeNumber;

            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            request.SetBizModel(model);

            AlipayTradeQueryResponse response = null;
            try
            {
                response = client.Execute(request);
                return new PaymentQueryResult
                {
                    Body = response.Body
                };

            }
            catch (Exception exp)
            {
                throw exp;
            }
        }
        
        public override PaymentReturnResult PaymentReturn(PaymentReturnParams paras)
        {
            if (paras.Request == null || paras.Request.Count == 0)
            {
                throw new Exception("Alipay同步验证无参数");
            }

            //bool flag = AlipaySignature.RSACheckV1(paras.Request, _alipayConfig.AlipayPublicKey, AlipayConfig.Charset, AlipayConfig.SignType, false);

            //if (!flag)
            //{
            //    throw new Exception("Alipay同步验证失败");
            //}
                
            // 同步验证通过
            return new PaymentReturnResult
            {
                Success = true,
                IsPaid = true,
                TotalAmount = double.Parse(paras.Request["total_amount"]),
                OrderNumber = paras.Request["out_trade_no"],
                TradeNumber = paras.Request["trade_no"]
            };
        }

        public override RefundQueryResult RefundQuery(RefundQueryParams paras)
        {
            IAopClient client = _alipayConfig.GetAopClientInstance();
            
            AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel
            {
                OutTradeNo = paras.OrderNumber,
                TradeNo = paras.TradeNumber,
                OutRequestNo = paras.RefundNumber
            };

            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
            request.SetBizModel(model);

            AlipayTradeFastpayRefundQueryResponse response = null;
            try
            {
                response = client.Execute(request);
                return new RefundQueryResult
                {
                    Body = response.Body
                };
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }

        public override RefundResult Refund(RefundParams paras)
        {
            IAopClient client = _alipayConfig.GetAopClientInstance();

            AlipayTradeRefundModel model = new AlipayTradeRefundModel
            {
                OutTradeNo = paras.OrderNumber,
                TradeNo = paras.TradeNumber,
                RefundAmount = paras.RefundAmount.ToString(),
                RefundReason = paras.RefundReason,
                OutRequestNo = paras.RefundNumber
            };

            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            request.SetBizModel(model);

            AlipayTradeRefundResponse response = null;
            try
            {
                response = client.Execute(request);
                return new RefundResult
                {
                    Body = response.Body
                };
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }
    }
}
